(function(){
	var View = $.IObject({
		init:function(op){
			$.extend(true,this,op);
			this.buildTmpl();
			//是否自动布局
			if(op.autoLayout !== false)
				this._inLayout = true;
			//执行自定义初始化事件并销毁
			if(this.onInit)
			{
				this.onInit();
				delete this.onInit;
			}
		},
		 buildContent:function(data,renderType){
            var content;
            if(data)
            {
                if($.isArray(data))
                {
                    var html = [];
                    for(var i = 0,d;d = data[i];i++){
                        this.modal.data(d);
                        html.push(Ccay.View.bindTmpl(this,renderType));
                    }
                    return html.join("");
                }
                this.modal.setData(data);
            }
            return Ccay.View.bindTmpl(this,renderType);
        },
		//渲染区域
		render:function(panel,renderType,data){
			panel = $(panel);
			renderType || (renderType = this.renderType);
			this.layout && (this.layout.renderType = renderType);
			
			this.tmpl && panel.append(this.buildContent(data,renderType));
			
			Ccay.Control.build(panel,this.modal,renderType,this.validOp,this.buildControlTag === false);
			return new Ccay.Controller({modal:this.modal,dom:panel,events:this.events});
		},
		//触发事件
//		trigger:function(name,op){
//			var ev = this.modal[name];
//			ev && ev.call(this.modal,op);
//		},
		//根据name获取field
		getField:function(name){
			var op = Ccay.DataHelper.getObj(name,this.modal,true);
			if(!op){
				op = this.modal[name.substr(name.indexOf(".")+1)]
			}
			return op;
		},
		//手动开启布局方法
		startLayout:function(){
			if(this.layout)
			{
				this._inLayout = true;
				return this.layout.start();
			}
		},
		//手动关闭布局方法
		endLayout:function(){
			if(this._inLayout)
			{
				delete this._inLayout;
				return this.layout.end();
			}
		},
		//开启自定义布局方法
		startCustomLayout:function(field){
            this._inLayout = null;
            var html = this.layout.getItemLayout(field,"${content}").split("${content}");
            this._customLayout = html[1];
            return html[0];
        },
        //关闭自定义布局方法
        endCustomLayout:function(){
            this._inLayout = true;
            var endHtml = this._customLayout;
            delete this._customLayout;
            return endHtml;
        },
        //生成模板
        buildTmpl:function(tmpl){
        	tmpl && (this.op.tmpl = tmpl);
        	Ccay.View.buildTmpl(this);
        }
	});
	
	Ccay.Controller = $.IObject({
		init:function(op){
			this.setup(op);
			$.extend(true,this,op);
		},
		setup:function(op){
			var panel = op.dom || this.dom,self = this;
			if(op.events)
			{
				$.each(op.events,function(ev,fn){
					var tm = ev.split(" "),
						target = tm[0],
						evName = tm[1];
						
					panel.find(target).bind(evName,self,function(e){
						fn.call(this,e,e.data);
					});
				})
				delete op.events;
			}
			this.bindChangeTrigger(panel,op);
			return this;
		},
		bindChangeTrigger:function(panel,op){
			if(op.changeTrigger)
			{
				panel.focusin(this,function(e){
					e.data.triggerChange(e);
				}).focusout(this,function(e){
					e.data.triggerChange(e);
				});
				(op.modal || this.modal).bindChange("viewChange",function(name,value,oldValue,view){
					view.findByName(name).manager().setValue(value);
				});
			}
		},
		triggerChange:function(e){
			var target = $.getEventTarget(e),
				name = target.attr('name'),ns;
				
			if(name)
				this.modal.attr(name,Ccay.Control.ctrValue(target,this.modal),this,"view");
		},
		valid:function(){
			return Ccay.Control.valid(this.dom);
		},
		find:function(selector){
			return this.dom.find(selector);
		},
		findByName:function(name){
			return this.dom.find('[name="'+ name + '"]');
		},
		getData:function(type){
			return Ccay.Control.getValue(this.dom,this.modal,type == null ? "edit" : type);
		},
		setData:function(data,type){
			Ccay.Control.setValue(this.dom,this.modal,data,type);
		}
	});

	var _Tmpl = Ccay.Tmpl = {
		convert:function(tmpl,fnMatch,op){
			//模板定义转化
			return tmpl.replace(/\r|\n/g,"")
		    		.replace(/("|\\)/g,"\\$1")
		    		.replace(/\<\%([\s\S]*?)\%\>/g, '");\n $1 _s.push("')
		            .replace(/\${([\s\S]*?)}/g,function(item,matched){
	            	return fnMatch(matched,op);
	        });
		},
		build:function(tmpl,fnMatch,args,op){
			//模板定义转化
			tmpl = this.convert(tmpl,fnMatch,op);   
	    	return new Function(args,'var _s=[];_s.push("'+ tmpl +'"); return _s;');
		},
		//绑定模板
		bind:function(fnTmpl,args,scope){
			return fnTmpl.apply(scope,args);
		}
	};
	
	Ccay.View = {
		//创建View
		create:function(op){
			return new View(op);
		},
		//初始化布局对象
		initLayout:function(view){
			var layout = view.layout;
			if(layout && typeof(layout) == 'string')
				view.layout = Ccay.ViewLayout.build(layout);
		},
		//编译模板
		buildTmpl:function(view){
			this.initLayout(view);
			var tmpl = view.tmpl;
			if(tmpl && typeof(tmpl) == 'string')
				view.tmpl = _Tmpl.build(tmpl,this.buildFiledItem,[view.modal.modalName,"renderType"],view);
		},
		//绑定模板
		bindTmpl:function(view,renderType){
			var tmpl = _Tmpl.bind(view.tmpl,[view.modal,renderType || op.renderType],view).join("");
			//替换模板变量方法
			if(view.layout.replaceVar)
				return view.layout.replaceVar(tmpl);
				
			return tmpl;
		},
		//编译模板字段
		buildFiledItem:function (matched,view,curField) {
        	var sign = matched.charAt(0),field,renderType;
        	if(sign == '#')
        		renderType = "edit";
        	else if(sign == '&')
        		renderType = "view";
        	else if(sign == '=')
        		renderType = "custom";
        	
        	field = renderType ? matched.substring(1) :  matched;

        	var fieldOp,content = ['",'];
        	//自定义渲染
        	if(renderType == "custom")
				content.push(field);
			else
			{
				fieldOp = view.getField(field,view);
				//判断是否可用或者为自定义模板模式下
				if(fieldOp.enable !== false || curField){
					//当为自定义渲染模板时
					if(fieldOp.renderTmpl && field != curField)
					{
						var tmpl = _Tmpl.convert(fieldOp.renderTmpl,function(matched,op){
							return Ccay.View.buildFiledItem(matched,op,field);
						},view);
						//添加自定义布局的方法
						return "\",this.startCustomLayout("+ field + "),\"" + tmpl + "\",this.endCustomLayout(),\"";
					}
					else
						content.push('Ccay.View.formatField(',field,',"',field,'",',renderType ? '"' + renderType + '"' : 'renderType' ,',this)');
				}
				else
					return "";
			}
        	content.push(',\n"');
        	return content.join("");
	    },
	    //格式化输出字段
		formatField:function(field,fieldName,renderType,view){
			field.renderType && (renderType = field.renderType);
			var content = Ccay.Control.buildCtrTag(fieldName,renderType);
			
			//判断是否使用布局渲染
			if(field.renderLayout !== false && view._inLayout && view.layout)
				return view.layout.getItemLayout(field,content);

			return content;
		}
	};

	var viewLayout = {
		//初始化布局
		init:function(op){
			this.itemCount = 0;
			this.html = [];
			$.extend(this,op);
		},
		//partStart : 模板项区域开始模板,
		//layout : 模板项模板,
		//partEnd : 模板项区域结束模板,
		//检查模板项区域方法
		checkPart:function(){},
		//检查模板项区域结束方法
		checkPartEnd:function(){},
		//添加区域开始模板
		beginPart:function(item){
			this.html.appendFormat(this.partStart,this.setPartOp(item));
		},
		//添加区域结束模板
		endPart:function(item){
			this.html.push(this.partEnd);
		},
		//设置区域绑定属性
		setPartOp:function(item){
			return item;
		},
		//设置模板项绑定属性
		setItemOp:function(item){},
		//添加模板项
		append:function(item,content){
			this.setItemOp(item);
			var layout = this.layout.replace(/\${([\s\S]*?)}/g,function(s,matched){
	            	if(matched == 'item')
	            		return content;
	            	else
	            	{
	            		return Ccay.DataHelper.getObj(matched,item,true) || "";
	            	}
	            });
	        this.itemCount++;
	        return this.html.push(layout);
		},
		//获取完整模板项布局
		getItemLayout:function(item,content,renderType){
			this.html = [];
			this.checkPart(item);
			this.append(item,content,renderType);
			this.checkPartEnd(item);
	        return this.html.join("");
		},
		//布局开始方法
		start:function(){},
		//布局结束方法
		end:function(){
			this.html = [];
			this.itemCount = 0;
			return this.partEnd;
		}
	};
	//布局适配器对象
	Ccay.ViewLayout = $.IAdapter({
		mapping:viewLayout,
		proto:{
			build:function(type,op)
			{
				if(typeof(type) == 'string')
				{
					var layout = this.get(type);
					return layout ? new layout(op) : null;
				}
				return new type(op);
			}
		},
		type:"object"
	})
})();













